package com.jsm.tf.net.protocol.serialize;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import lombok.Cleanup;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

public class KryoSerializer implements Serializer {
    // *这个东西线程不安全*
    private static final ThreadLocal<Kryo> KRYO = ThreadLocal.withInitial(() -> {
        Kryo kryo = new Kryo();
        kryo.setInstantiatorStrategy(new Kryo.DefaultInstantiatorStrategy());
        return kryo;
    });

    @Override
    public <T> T deserialize(Class<T> clazz, byte[] bytes) throws IOException {
        KRYO.get().register(clazz);
        @Cleanup ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
        @Cleanup Input input = new Input(bis);
        return (T) KRYO.get().readObject(input, clazz);
    }

    @Override
    public <T> byte[] serialize(T object) throws IOException {
        KRYO.get().register(object.getClass());
        @Cleanup ByteArrayOutputStream bos = new ByteArrayOutputStream();
        @Cleanup Output output = new Output(bos);
        KRYO.get().writeObject(output, object);
        output.flush();
        return bos.toByteArray();
    }
}
